package com.lihang.rabbit1.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Arrays;
import java.util.List;

/**
 * 全局跨域配置
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Value("${cors.allowed-origins:*}")
    private String allowedOrigins;

    @Value("${cors.allowed-methods:*}")
    private String allowedMethods;

    @Value("${cors.allowed-headers:*}")
    private String allowedHeaders;

    @Value("${cors.allow-credentials:true}")
    private boolean allowCredentials;

    @Value("${cors.max-age:3600}")
    private long maxAge;

    /**
     * 添加CORS映射
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 应用到所有路径
                .allowedOriginPatterns(getAllowedOriginArray())
                .allowedMethods(getAllowedMethodArray())
                .allowedHeaders(getAllowedHeaderArray())
                .allowCredentials(allowCredentials)
                .maxAge(maxAge);
    }

    /**
     * 创建CorsFilter Bean
     */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        List<String> origins = Arrays.asList(getAllowedOriginArray());

        if (origins.contains("*")) {
            config.addAllowedOriginPattern("*");
        } else {
            origins.forEach(config::addAllowedOrigin);
        }

        config.setAllowCredentials(allowCredentials);

        if ("*".equals(allowedMethods)) {
            config.addAllowedMethod("*");
        } else {
            for (String method : getAllowedMethodArray()) {
                config.addAllowedMethod(method);
            }
        }

        if ("*".equals(allowedHeaders)) {
            config.addAllowedHeader("*");
        } else {
            for (String header : getAllowedHeaderArray()) {
                config.addAllowedHeader(header);
            }
        }

        config.setMaxAge(maxAge);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);

        return new CorsFilter(source);
    }

    private String[] getAllowedOriginArray() {
        return allowedOrigins.split(",");
    }

    private String[] getAllowedMethodArray() {
        return allowedMethods.split(",");
    }

    private String[] getAllowedHeaderArray() {
        return allowedHeaders.split(",");
    }
}